import java.awt.Container;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import brut.androlib.res.decoder.AXmlResourceParser;

import android.util.TypedValue; 

public class M {
	public static final int FRAMEW = 600, FRAMEH=500;
	static FileDialog  fileDialog;
	static JLabel savepath;
	static JTextField jpath;
	static String imgpath;
	static JTextArea msg;
	
	public static void main(String[] args) {
	/*	try
		{
		 ClassPool pool = ClassPool.getDefault();
	        //设置目标类的路径
	        pool.insertClassPath("d:/eclipsepro/loadtizi/");
	        //获得要修改的类
	        CtClass cclass = pool.get("com.linkin.tv.MainActivity");
	        //设置方法需要的参数
	        CtClass[] param = new CtClass[0] ;
	       // param[0] = pool.get("java.lang.String") ;
	        //得到方法
	        CtMethod method = cclass.getDeclaredMethod("c",param);
	        //插入新的代码
	       // method.insertBefore("{return \"no ,\" + $1;}");//$1表示第一个参数
	        method.setBody("{return false;}");
	        //保存到文件里
	        cclass.writeFile("d:/eclipsepro/loadtizi/com/");
		}catch(Exception e)
		{
			e.printStackTrace();
		}*/
		//new M().getSingInfo();
		//unZip("d:/dszbChannelDecrypt.apk");
//		 String [] curArr="2.0.0".split("\\.");
//		 System.out.println(curArr+" = "+curArr.length);
//		ArrayList<Tbean> list = 	(ArrayList<Tbean>) new M().test(Tbean.class);
//		System.out.println(list);
		JFrame frame = new JFrame();
		frame.setResizable(false);
		frame.setDefaultCloseOperation(3);
		Dimension displaySize = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setBounds((displaySize.width-FRAMEW)/2, (displaySize.height-FRAMEH)/2,FRAMEW,FRAMEH);
		Container contain = frame.getContentPane();
		
		contain.setLayout(null);
		
		frame.setTitle("升级信息生成工具");
		JButton bofile = new JButton("打开");
		 jpath = new JTextField();
		 msg = new JTextArea();
		 JScrollPane smsg = new JScrollPane(msg,
					ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
					ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		 msg.setLineWrap(true);
		 bofile.setBounds(FRAMEW-60, 0, 60, 20);
			jpath.setBounds(0, 0, FRAMEW-60, 20);
			smsg.setBounds(0, 25, FRAMEW, FRAMEH-40);
			
			contain.add(bofile);
			contain.add(jpath);
			contain.add(smsg);
			 fileDialog = new FileDialog(frame);
			 
			 MouseListener ml = new MouseListener()
				{

					@Override
					public void mouseClicked(MouseEvent evn) {
						fileDialog.setVisible(true);
						fileDialog.setMode(FileDialog.LOAD);
						imgpath = fileDialog.getDirectory()+"img/";
						
						jpath.setText(fileDialog.getDirectory()+fileDialog.getFile());
						//msg.setText("MD5: "+MD5Util.getFileMD5String(new File(fileDialog.getDirectory()+fileDialog.getFile())));
						
						String[] arr =unZip(fileDialog.getDirectory()+fileDialog.getFile());
						String otxt =
						"{\n"+
							" \"TestIP\": \"\",\r\n"+
				            " \"version\": \""+arr[0]+"\",\r\n"+
				            " \"url\": \"\",\r\n"+
				            " \"md5\": \""+arr[2]+"\",\r\n"+
				            " \"rsaMd5\":\""+arr[3]+"\",\r\n"+//签名md5
				            " \"msg\": [\r\n"+
				        
				        "]\r\n}\r\n";
						msg.setText(otxt+fileDialog.getDirectory()+arr[1].replaceAll("\\.", "_")+".json");
						try {
							FileOutputStream out = new FileOutputStream(fileDialog.getDirectory()+arr[1].replaceAll("\\.", "_")+".json");
							out.write(otxt.getBytes());
							out.close();
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

					@Override
					public void mouseEntered(MouseEvent arg0) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void mouseExited(MouseEvent arg0) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void mousePressed(MouseEvent arg0) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void mouseReleased(MouseEvent arg0) {
						// TODO Auto-generated method stub
						
					}
					
				};
				bofile.addMouseListener(ml );
		frame.setVisible(true);
	}
	
	public  List test(Class<?> bean)
	{
		try {
			
			Method setname = bean.getMethod("setName", String.class);
			Method setFlag = bean.getMethod("setFlag", Integer.class);
			List list = new ArrayList();
			for(int i=0; i < 3; i++)
			{
				Object obj = bean.newInstance();			
				setname.invoke(obj, "sf"+i);
				setFlag.invoke(obj, i);
				list.add( obj);
			}
			return list;
			
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
public void getSingInfo() {  
    try {  
        
    	File file = new File("dszbChannelDecrypt.apk");
    	ByteArrayOutputStream  readstr = new ByteArrayOutputStream ();
		try {
			FileInputStream fread = new FileInputStream(file);
			byte[] buf = new byte[4096];
			int len;
			
			while((len = fread.read(buf, 0, 4096)) != -1 )
			{
				readstr.write(buf, 0, len);
			}
			fread.close();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

        MessageDigest md = MessageDigest.getInstance("MD5");

        md.update(readstr.toByteArray());

        byte[] digest = md.digest(); 

        String res = toHexString(digest);

        System.out.println("apk md5 = "+res);

       
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
}  
private void byte2hex(byte b, StringBuffer buf) {

    char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',

                        '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    int high = ((b & 0xf0) >> 4);

    int low = (b & 0x0f);

    buf.append(hexChars[high]);

    buf.append(hexChars[low]);

}
private String toHexString(byte[] block) {

    StringBuffer buf = new StringBuffer();


    int len = block.length;


    for (int i = 0; i < len; i++) {

         byte2hex(block[i], buf);

         if (i < len-1) {

             buf.append(":");

         }

    }

    return buf.toString();

}

public static String[] unZip(String apkUrl) 
{   
	  //[0]:版本号;[1]包名 [2] md5 [3] rsamd5
   String[] st = new String[4];
   
   byte b[] = new byte [1024];
   int length; 
   ZipFile zipFile;
   st[2]=MD5Util.getFileMD5String(new File(apkUrl));
   try {
       zipFile = new ZipFile( new File(apkUrl));       
       Enumeration enumeration = zipFile.entries();
       ZipEntry zipEntry = null ;           
       while (enumeration.hasMoreElements()) {
          zipEntry = (ZipEntry) enumeration.nextElement();           
          if (zipEntry.isDirectory()) {
             
          } else {
              if("AndroidManifest.xml".equals(zipEntry.getName()))
              {
          		try {
          			AXmlResourceParser parser=new AXmlResourceParser();
          			parser.open(zipFile.getInputStream(zipEntry));
          			while (true) {
          				int type=parser.next();
          				if (type==1) {
          					break;
          				}
          				switch (type) {
          					case 2:
          					{
          						for (int i=0;i!=parser.getAttributeCount();++i) {
          							if("versionName".equals(parser.getAttributeName(i))){
          								st[0] = getAttributeValue(parser,i);
          								System.out.println("\tversion  "+st[0]);
          							}else if("package".equals(parser.getAttributeName(i))){
          								st[1] = getAttributeValue(parser,i);
          							}
          						}
          					}
          				}
          			}
          		}
          		catch (Exception e) {
          			e.printStackTrace();
          		}
              }
              
              if("META-INF/CERT.RSA".equals(zipEntry.getName())){
            	  OutputStream outputStream = new FileOutputStream("c.rs");
                  InputStream inputStream = zipFile.getInputStream(zipEntry); 
                  while ((length = inputStream.read(b)) > 0)
                     outputStream.write(b, 0, length);
                  outputStream.flush();
                  outputStream.close();
                  Process process = null;  
                  List<String> processList = new ArrayList<String>();  
                  try {  
                      process = Runtime.getRuntime().exec("keytool -printcert -file c.rs");  
                      BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));  
                      String line = "";  
                      while ((line = input.readLine()) != null) {  
                    	  if(line.contains("MD5:"))
                    	  {
                    		  line = line.trim().substring(4);
                    		  line = line.replaceAll("\\:", "");
                    		  st[3] = line.trim();
                    		  System.out.println(line);
                    		  break;
                    	  }
//                          processList.add(line);  
                      }  
                      input.close();  
                  } catch (IOException e) {  
                      e.printStackTrace();  
                  }  
                  
//                  for (String line : processList) {  
//                      System.out.println("line: "+line);  
//                  }  
              }
          }
       }
   } catch (IOException e) {
       // TODO Auto-generated catch block
       //e.printStackTrace();
   }
   return st;
}

private static String getAttributeValue(AXmlResourceParser parser,int index) {
	return parser.getAttributeValue(index);
		/*int type=parser.getAttributeValueType(index);
		int data=parser.getAttributeValueData(index);
		if (type==TypedValue.TYPE_STRING) {
			return parser.getAttributeValue(index);
		}
		if (type==TypedValue.TYPE_ATTRIBUTE) {
			return String.format("?%s%08X",getPackage(data),data);
		}
		if (type==TypedValue.TYPE_REFERENCE) {
			return String.format("@%s%08X",getPackage(data),data);
		}
		if (type==TypedValue.TYPE_FLOAT) {
			return String.valueOf(Float.intBitsToFloat(data));
		}
		if (type==TypedValue.TYPE_INT_HEX) {
			return String.format("0x%08X",data);
		}
		if (type==TypedValue.TYPE_INT_BOOLEAN) {
			return data!=0?"true":"false";
		}
		if (type==TypedValue.TYPE_DIMENSION) {
			return Float.toString(complexToFloat(data))+
				DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
		}
		if (type==TypedValue.TYPE_FRACTION) {
			return Float.toString(complexToFloat(data))+
				FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
		}
		if (type>=TypedValue.TYPE_FIRST_COLOR_INT && type<=TypedValue.TYPE_LAST_COLOR_INT) {
			return String.format("#%08X",data);
		}
		if (type>=TypedValue.TYPE_FIRST_INT && type<=TypedValue.TYPE_LAST_INT) {
			return String.valueOf(data);
		}
		return String.format("<0x%X, type 0x%02X>",data,type);*/
	}

private static String getPackage(int id) {
		if (id>>>24==1) {
			return "android:";
		}
		return "";
	}

/////////////////////////////////// ILLEGAL STUFF, DONT LOOK :)
	public static float complexToFloat(int complex) {
		return (float)(complex & 0xFFFFFF00)*RADIX_MULTS[(complex>>4) & 3];
	}
	
	private static final float RADIX_MULTS[]={
		0.00390625F,3.051758E-005F,1.192093E-007F,4.656613E-010F
	};
	private static final String DIMENSION_UNITS[]={
		"px","dip","sp","pt","in","mm","",""
	};
	private static final String FRACTION_UNITS[]={
		"%","%p","","","","","",""
	};

}
